import React, {
  Component,
  createRef,
  createContext,
  useRef,
  useState,
  useEffect,
} from "react";
import PropType from "prop-types";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import gsap from "gsap"; //动画库
import Stats from "stats.js"; //性能监控
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js"; // FBX 模型加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; //模型加载器
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; //模型解压缩

import "./Home.css";
import TagHook from "./components/tagHook";

import { CSS2DObject } from "three/examples/jsm/renderers/CSS2DRenderer.js"; //// 引入CSS2模型对象CSS2DObject
import { CSS2DRenderer } from "three/examples/jsm/renderers/CSS2DRenderer.js"; // 引入CSS2渲染器CSS2DRenderer


import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'; //EffectComposer 效果组合器 它是处理 WebGLRenderer 效果的 接收 renderer为参数
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'; // RenderPass 处理通道 它是处理 scene 场景和相机 camera 的。 接收 scene camera 为参数
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';//UnrealBloomPass 泛光通道
import { FXAAShader } from 'three/examples/jsm/shaders/FXAAShader.js'; //添加抗锯齿的效果
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass'; // 高亮发光描边通道 OutlinePass(画布宽高二维向量，场景scene,相机camera)

import {SMAAPass} from 'three/examples/jsm/postprocessing/SMAAPass.js'; // SMAA抗锯齿通道

import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass';
import {GammaCorrectionShader} from 'three/examples/jsm/shaders/GammaCorrectionShader.js';// 伽马校正后处理Shader

const width = window.innerWidth; //屏幕宽度
const height = window.innerHeight; //屏幕高度

// 渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true, //开启优化锯齿
});
renderer.setPixelRatio(window.devicePixelRatio); // 设置设备像素比。通常用于避免HiDPI设备上绘图模糊
renderer.setSize(width, height); // 将输出canvas的大小调整为(width, height)并考虑设备像素比，

// 相机
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
camera.position.set(82, 53, 165);
camera.lookAt(0, 0, 0);
// 场景
const scene = new THREE.Scene();

// glb模型加载器
const loader = new GLTFLoader();

// 轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 12, 0);

// 性能监测 (这个不是three必须项)
const stats = new Stats(); // 性能监测

// 创建一个CSS2渲染器CSS2DRenderer
const css2Renderer = new CSS2DRenderer();
css2Renderer.setSize(width, height);
// HTML标签<div id="tag"></div>外面父元素叠加到canvas画布上且重合
css2Renderer.domElement.style.position = "absolute";
css2Renderer.domElement.style.top = "0px";
//设置.pointerEvents=none，解决HTML元素标签对threejs canvas画布鼠标事件的遮挡
css2Renderer.domElement.style.pointerEvents = "none";

// 灯光
const directionalLight = new THREE.PointLight(0xffffff, 1, 100);
directionalLight.position.y = 10;
scene.add(directionalLight);
const light = new THREE.AmbientLight(0xffffff); //环境灯光
scene.add(light);

//辉光渲染通道
const composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
const v2 = new THREE.Vector2(width, height);
const outlinePass = new OutlinePass(v2, scene, camera);
outlinePass.visibleEdgeColor.set(0x00ffff); //模型描边颜色，默认白色 
outlinePass.edgeThickness = 1; //高亮发光描边厚度
outlinePass.edgeStrength =16; //高亮描边发光强度
outlinePass.pulsePeriod = 0; //模型闪烁频率控制，默认0不闪烁
composer.addPass(outlinePass);

// SMAAPass抗锯齿通道
const pixelRatio = renderer.getPixelRatio();
const smaaPass = new SMAAPass(width * pixelRatio, height * pixelRatio);
composer.addPass(smaaPass);

// 创建伽马校正通道（解决模型色差的问题）
const gammaPass = new ShaderPass(GammaCorrectionShader);
composer.addPass(gammaPass);


const modelGroup = new THREE.Group(); //组
let chooseObj: any = null;
let threeDOM:any =null;
const ReactDemo = () => {
 
 
  let tag: any = null;

  const [tagName,setTagName]=useState<string>('')

  const [value1,setvalue1]=useState<number>(100)

  useEffect(() => {
    animate();
    init();
  
  }, []);

  const handleClick=(v:any)=>{
    threeDOM =v
  }

  function init() {
    threeDOM.style.top = '-161px'; //指示线端点放在标注点附近
    tag = new CSS2DObject(threeDOM as HTMLElement);
   
    const container = document.createElement("div");
    document.body.appendChild(container);

    const light = new THREE.AmbientLight(0x404040); // 环境光会均匀的照亮场景中的所有物体。
    scene.add(light);

    const axesHelper = new THREE.AxesHelper(90); // 辅助线
    scene.add(axesHelper);

    // 性能监测
    container.appendChild(stats.dom);

    loader.load("./3D/工厂.glb", function (gltf) {
      modelGroup.add(gltf.scene);
      scene.add(modelGroup); //三维场景添加到model组对象中
    });

    document.body.appendChild(css2Renderer.domElement);

    container.appendChild(renderer.domElement);

    window.addEventListener("resize", onWindowResize);
    renderer.domElement.addEventListener("click", handleModelClick);
  }

  function onWindowResize() {
    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    renderer.setSize(width, height);
  }

  function handleModelClick(event: MouseEvent) {
 
    const raycaster = new THREE.Raycaster();
    const pointer = new THREE.Vector2();
    pointer.x = (event.clientX / width) * 2 - 1;
    pointer.y = -(event.clientY / height) * 2 + 1;
    // 通过摄像机和鼠标位置更新射线
    raycaster.setFromCamera(pointer, camera);
    const cunchu:any = modelGroup.getObjectByName('存储罐');
  
    for (let i = 0; i < cunchu!.children.length; i++) {
      const group = cunchu!.children[i];
    
      group.traverse(function (obj:any) {
        if (obj && obj.isMesh) {
          obj.ancestors = group;
         
        }
      });
    }
    // 计算物体和射线的焦点
    const intersects:any = raycaster.intersectObjects(cunchu.children);
    outlinePass.selectedObjects = [] //清空 发光模型对象
    if (intersects.length > 0) {
  
    
    outlinePass.selectedObjects.splice(0,1,intersects[0].object.ancestors) // 新增模型对象

     setvalue1(Math.floor(Math.random() * 100) + 1)

    
      setTagName(intersects[0].object.name)
      
      console.log( intersects[0].object.ancestors,' intersects[0].object intersects[0].object',tag)
    
    
      intersects[0].object.ancestors.add(tag);
    
      chooseObj = intersects[0].object.ancestors;
     
    } else {
      if (chooseObj) {
        //把原来选中模型对应的标签和发光描边隐藏

        chooseObj.remove(tag); //从场景移除
      }
    }
   
   
  }

  //

  function animate() {
    requestAnimationFrame(animate);
    css2Renderer.render(scene, camera);
    // renderer.render(scene, camera);
    controls.update();
    composer.render();
    stats.update();
  }
  return (
    <div style={{ background: "black" }}>
      <TagHook handleClick={handleClick}    tagName={tagName} value1={value1} />
    </div>
  );
};

export default ReactDemo;
